home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / vroom / quickcull.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  5.4 KB  |  282 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include <math.h>
  19. #include <malloc.h>
  20. #include <GL/gl.h>
  21.  
  22. #include "quickcull.h"
  23.  
  24.  
  25. struct _qcDetail {
  26.     int    minLod ;
  27.     int    maxLod ;
  28.     float    minZ ;
  29.     float    maxZ ;
  30.     float    radius ;
  31.     } ;
  32.     
  33.  
  34. /* BEGIN PROTOTYPES -S quickcull.c */
  35. /* END PROTOTYPES -S quickcull.c */
  36.  
  37.  
  38. static float    cpwi ;
  39. static float    spw ;
  40. static float    tpw ;
  41. static float    cphi ;
  42. static float    sph ;
  43. static float    tph ;
  44. static float    zN ;
  45. static float    zF ;
  46. static float    re[3] ;
  47. static float    vl[3] ;
  48. static float    vw[3] ;
  49. static float    vh[3] ;
  50.  
  51.  
  52. /*------------------------------------------------------------------------------
  53.  * Initialize the viewing volume.
  54.  *----------------------------------------------------------------------------*/
  55. int
  56. qcInit(
  57.     float    w,        /* Half width of view volume at near plane */
  58.     float    h,        /* Half height of view volume at near plane */
  59.     float    zNear,        /* Near clipping plane */
  60.     float    zFar        /* Far clipping plane */
  61.     )
  62. {
  63.     float    lw ;
  64.     float    lh ;
  65.  
  66.     
  67.     if( w <= 0.0f || h <= 0.0f || zNear >= zFar || zNear < 0.0f )
  68.     {
  69.         return( 0 ) ;
  70.     }
  71.  
  72.     lw = sqrtf( w * w + zNear * zNear ) ;
  73.     cpwi = lw / zNear ;
  74.     spw = w / lw ;
  75.     tpw = w / zNear ;
  76.  
  77.     lh = sqrtf( h * h + zNear * zNear ) ;
  78.     cphi = lh / zNear ;
  79.     sph = h / lh ;
  80.     tph = h / zNear ;
  81.  
  82.     zN = zNear ;
  83.     zF = zFar ;
  84.  
  85.     return( 1 ) ;
  86. }
  87.  
  88.  
  89.  
  90. /*------------------------------------------------------------------------------
  91.  * Initialize the viewing orientation.
  92.  *----------------------------------------------------------------------------*/
  93. int
  94. qcSetView(
  95.     float    rEye[3],
  96.     float    vL[3],
  97.     float    vW[3],
  98.     float    vH[3]
  99.     )
  100. {
  101.     re[0] = rEye[0] ;
  102.     re[1] = rEye[1] ;
  103.     re[2] = rEye[2] ;
  104.  
  105.     vl[0] = vL[0] ;
  106.     vl[1] = vL[1] ;
  107.     vl[2] = vL[2] ;
  108.  
  109.     vw[0] = vW[0] ;
  110.     vw[1] = vW[1] ;
  111.     vw[2] = vW[2] ;
  112.  
  113.     vh[0] = vH[0] ;
  114.     vh[1] = vH[1] ;
  115.     vh[2] = vH[2] ;
  116. }
  117.  
  118.  
  119.  
  120. /*------------------------------------------------------------------------------
  121.  * Test an object for culling (return QC_CULLED if culled, LOD if not)
  122.  *----------------------------------------------------------------------------*/
  123. int
  124. qcCull(
  125.     float        v[3],        /* Object center */
  126.     qcDetail    qcd
  127.     )
  128. {
  129.     float    u[3] ;
  130.     float    l ;
  131.     float    w ;
  132.     float    s ;
  133.     float    d ;
  134.     float    h ;
  135.     float    r = qcd->radius ;
  136.     int    lod ;
  137.  
  138.     u[0] = v[0] - re[0] ;
  139.     u[1] = v[1] - re[1] ;
  140.     u[2] = v[2] - re[2] ;
  141.  
  142.     l = u[0] * vl[0] + u[1] * vl[1] + u[2] * vl[2] ;
  143.  
  144.     if( zF < l - r || zN > l + r )
  145.     {
  146.         return( QC_CULLED ) ;
  147.     }
  148.  
  149.     w = u[0] * vw[0] + u[1] * vw[1] + u[2] * vw[2] ;
  150.     if( w < 0.0f )
  151.     {
  152.         w = -w ;
  153.     }
  154.  
  155.     d = w * cpwi ;
  156.     s = ( l + w * tpw ) * spw ;
  157.  
  158.     if( s < d -r )
  159.     {
  160.         return( QC_CULLED ) ;
  161.     }
  162.  
  163.     h = u[0] * vh[0] + u[1] * vh[1] + u[2] * vh[2] ;
  164.     if( h < 0.0f )
  165.     {
  166.         h = -h ;
  167.     }
  168.  
  169.     d = h * cphi ;
  170.     s = ( l + h * tph ) * sph ;
  171.  
  172.     if( s < d -r )
  173.     {
  174.         return( QC_CULLED ) ;
  175.     }
  176.  
  177.     if( l <= qcd->minZ )
  178.     {
  179.         lod = qcd->minLod ;
  180.     }
  181.     else if( l >= qcd->maxZ )
  182.     {
  183.         lod = qcd->maxLod ;
  184.     }
  185.     else
  186.     {
  187.         lod = qcd->minLod + (int)( 0.5f +
  188.             ( (float)( qcd->maxLod - qcd->minLod )
  189.             * ( l - qcd->minZ ) / ( qcd->maxZ - qcd->minZ ) ) ) ;
  190.     }
  191.  
  192.     return( lod ) ;
  193. }
  194.  
  195.  
  196.  
  197. /*------------------------------------------------------------------------------
  198.  * Drawing bounding square of view volume.
  199.  *----------------------------------------------------------------------------*/
  200. void
  201. qcDraw(
  202.     float    z
  203.     )
  204. {
  205.     float    c[3] ;
  206.     float    dw[3] ;
  207.     float    dh[3] ;
  208.     float    w ;
  209.     float    h ;
  210.  
  211.     c[0] = re[0] + z * vl[0] ;
  212.     c[1] = re[1] + z * vl[1] ;
  213.     c[2] = re[2] + z * vl[2] ;
  214.  
  215.     w = tpw * z ;
  216.     dw[0] = w * vw[0] ;
  217.     dw[1] = w * vw[1] ;
  218.     dw[2] = w * vw[2] ;
  219.     h = tph * z ;
  220.     dh[0] = h * vh[0] ;
  221.     dh[1] = h * vh[1] ;
  222.     dh[2] = h * vh[2] ;
  223.  
  224.     glBegin( GL_LINE_LOOP ) ;
  225.         glVertex3f(c[0]+dw[0]+dh[0],c[1]+dw[1]+dh[1],c[2]+dw[2]+dh[2]);
  226.         glVertex3f(c[0]-dw[0]+dh[0],c[1]-dw[1]+dh[1],c[2]-dw[2]+dh[2]);
  227.         glVertex3f(c[0]-dw[0]-dh[0],c[1]-dw[1]-dh[1],c[2]-dw[2]-dh[2]);
  228.         glVertex3f(c[0]+dw[0]-dh[0],c[1]+dw[1]-dh[1],c[2]+dw[2]-dh[2]);
  229.     glEnd() ;
  230. }
  231.  
  232.  
  233.  
  234. /*------------------------------------------------------------------------------
  235.  * Create and initialize a qcDetail structure.
  236.  *----------------------------------------------------------------------------*/
  237. qcDetail
  238. qcCreateDetail(
  239.     int    minLod,
  240.     int    maxLod,
  241.     float    minZ,
  242.     float    maxZ,
  243.     float    radius
  244.     )
  245. {
  246.     qcDetail    qcd ;
  247.  
  248.     if( ( qcd = (qcDetail)malloc( sizeof( struct _qcDetail ) ) ) == NULL )
  249.     {
  250.         return( NULL ) ;
  251.     }
  252.  
  253.     qcSetLodRange( qcd, minLod, maxLod ) ;
  254.  
  255.     qcd->minZ = minZ ;
  256.     qcd->maxZ = maxZ ;
  257.     qcd->radius = radius ;
  258.  
  259.     return( qcd ) ;
  260. }
  261.  
  262.  
  263.  
  264. /*------------------------------------------------------------------------------
  265.  * Modify the lod range for a qcDetail.
  266.  *----------------------------------------------------------------------------*/
  267. void
  268. qcSetLodRange(
  269.     qcDetail    qcd,
  270.     int        minLod,
  271.     int        maxLod
  272.     )
  273. {
  274.     if( minLod < 0 || maxLod < minLod )
  275.     {
  276.         fprintf( stderr, "qcCreateDetail: bad LOD range\n" ) ;
  277.     }
  278.  
  279.     qcd->minLod = minLod ;
  280.     qcd->maxLod = maxLod ;
  281. }
  282.